package com.jxb.visibility;

/**
 * 在JVM层面保证可见性一共有2种方式
 *      上下文切换
 *      内存屏障
 * 在java层面保证可见性的方式有多种
 *      final关键字    --> jvm层面，StoreStore内存屏障
 *      synichronized锁      --> jvm层面，StoreLoad内存屏障
 *      lock锁
 *      Thread.sleep    --> jvm层面，上下文切换
 *      Thread.yield    --> jvm层面，上下文切换
 *      wait    -->jvm层面，内存屏障OrderAccess::fence()，硬件层面：lock前缀指令
 *      volatile关键字     -->jvm层面，内存屏障StoreLoad，硬件层面：lock前缀指令
 */
public class VisibilityDemo {

    private volatile boolean flag = true;

    public static void main(String[] args) throws InterruptedException {
        VisibilityDemo visibilityDemo = new VisibilityDemo();
        Thread thread = new Thread(() -> visibilityDemo.doWhile());
        thread.start();

        Thread.sleep(1000);

        Thread thread1 = new Thread(() -> visibilityDemo.refresh());
        thread1.start();
    }

    private void doWhile() {
        System.out.println(Thread.currentThread().getName() + "开始执行.....");
        int i = 0;
        while (flag) {
            i++;
            //1：使用了final关键字保证了可见性,jvm层面也是通过内存屏障实现的，StoreStroe
//            System.out.println("");
            //2：通过上下文切换保证了可见性
//            Thread.yield();
            //3：通过JVM层面的内存屏障去实现的,OrderAccess::fence();
//            try {
//                wait(1000);
//            }catch (Exception e) {
//
//            }
            //4：通过上下文切换保证了可见性，PeriodicTask::time_to_wait()
//            try {
//                Thread.sleep(1000);
//            }catch (Exception e) {
//
//            }
            //5：通过volatile关键字保证了可见性，是通过JVM层面的内存屏障实现的， OrderAccess::storeload()

        }
        System.out.println(Thread.currentThread().getName() + "跳出循环.....");
    }

    private void refresh() {
        flag = false;
        System.out.println(Thread.currentThread().getName() + "修改flag.....");
    }

}
